package org.ceteca.explica.client.gui;

import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.URL;

import javax.imageio.ImageIO;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;

public class ImageUtils {
	private static ImageUtils instance;

	private ImageUtils() {
	}

	public static ImageUtils getInstance() {
		if (instance == null)
			instance = new ImageUtils();

		return instance;
	}

	public Image loadImage(URL url) {
		InputStream is;
		try {
			is = url.openStream();
		} catch (IOException e) {
			return null;

		}
		return loadImage(is);

	}

	public Image resize(Image image, int width, int height) {
		Image scaled = new Image(Display.getCurrent(), width, height);
		GC gc = new GC(scaled);
		gc.setAntialias(SWT.ON);
		gc.setInterpolation(SWT.HIGH);
		gc.drawImage(image, 0, 0, image.getBounds().width,
				image.getBounds().height, 0, 0, width, height);
		// gc.dispose();
		image.dispose();
		return scaled;
	}

	public Image scale(Image image, int width, int height) {
		Image scaled = new Image(Display.getCurrent(), image.getImageData()
				.scaledTo(width, height));
		image.dispose();

		return scaled;
	}

	public Image loadImage(String imgFile) {
		Image img = new Image(Display.getCurrent(), imgFile);

		return img;
	}

	public Image loadImage(InputStream imgIs) {
		Image img = new Image(Display.getCurrent(), imgIs);

		return img;
	}

	public Image loadImage(ImageData imgData) {
		Image img = new Image(Display.getCurrent(), imgData);

		return img;
	}

	public Image loadImage(byte[] imgContents) {
		ImageData imgData = null;
		try {
			ByteArrayInputStream in = new ByteArrayInputStream(imgContents);
			DataInputStream readIn = new DataInputStream(in);

			imgData = new ImageData(readIn);
			readIn.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}

		Image img = new Image(Display.getCurrent(), imgData);

		return img;
	}

	public Image getScaledImage(String imgFile, int maxWidth, int maxHeight) {
		Image img = loadImage(imgFile);
		return this.getScaledImage(img, maxWidth, maxHeight);
	}

	public Image getScaledImage(InputStream imgIs, int maxWidth, int maxHeight) {
		Image img = loadImage(imgIs);
		return this.getScaledImage(img, maxWidth, maxHeight);
	}

	public Image getScaledImage(ImageData imgData, int maxWidth, int maxHeight) {
		Image img = loadImage(imgData);
		return this.getScaledImage(img, maxWidth, maxHeight);
	}

	public Image getScaledImage(byte[] imgContents, int maxWidth, int maxHeight) {
		Image img = loadImage(imgContents);
		return this.getScaledImage(img, maxWidth, maxHeight);
	}

	private Image getScaledImage(Image image, int maxWidth, int maxHeight) {
		int widthHint = Math.min(image.getImageData().width, maxWidth);
		int heightHint = Math.min(image.getImageData().height, maxHeight);

		float widthPerc = (float) widthHint
				/ (float) image.getImageData().width;
		float heightPerc = (float) heightHint
				/ (float) image.getImageData().height;

		float scalePerc = Math.min(widthPerc, heightPerc);

		widthHint = Math.round(image.getImageData().width * scalePerc);
		heightHint = Math.round(image.getImageData().height * scalePerc);

		System.out
				.println(String
						.format(
								"SCALING IMAGE... ORIGINAL: (%d, %d) AVAILABLE: (%d, %d) SCALE: (%f, %f)\nFINAL SCALE: %f%% FINAL SIZE: (%d, %d)",
								image.getImageData().width, image
										.getImageData().height, maxWidth,
								maxHeight, widthPerc, heightPerc, scalePerc,
								widthHint, heightHint));

		Image scaledImg = this.scale(image, widthHint, heightHint);
		image.dispose();

		return scaledImg;
	}

	public byte[] getImageContents(String filename) {
		try {
			File f = new File(filename);
			if (f.exists() && f.canRead()) {
				// Open an input stream to read the file contents
				FileInputStream is = new FileInputStream(f);

				// Get the size of the file
				long length = f.length();

				if (length > Integer.MAX_VALUE) {
					return null;
				}

				// Create the byte array to hold the data
				byte[] bytes = new byte[(int) length];

				// Read in the bytes
				int offset = 0;
				int numRead = 0;
				while (offset < bytes.length
						&& (numRead = is.read(bytes, offset, bytes.length
								- offset)) >= 0) {
					offset += numRead;
				}

				// Ensure all the bytes have been read in
				if (offset < bytes.length) {
					return null;
				}

				// Close the input stream and return bytes
				is.close();

				return bytes;
			} else
				return null;
		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}

	}


	public java.awt.Image convertImage(Image img){
		if (img==null)
			return null;
		ImageLoader loader=new ImageLoader();
		
	
		loader.data=new ImageData[]{img.getImageData()};
		loader.save("test.bmp", SWT.IMAGE_BMP);
		BufferedImage image=null;
		try {
			image = ImageIO.read(new FileInputStream("test.bmp"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return image;
	}






	
}
